package cn.imvc.data.jpa.repository;

import static org.springframework.data.querydsl.QueryDslUtils.QUERY_DSL_PRESENT;
import java.io.Serializable;
import javax.persistence.EntityManager;
import org.apache.log4j.Logger;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.QueryDslJpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;

public class IJpaRepositoryFactory extends JpaRepositoryFactory {
	static Logger logger = Logger.getLogger(IJpaRepositoryFactory.class);
	private final EntityManager iEntityManager;

	public IJpaRepositoryFactory(EntityManager entityManager) {
		super(entityManager);
		this.iEntityManager = entityManager;
	}

	@Override
	protected Object getTargetRepository(RepositoryInformation information) {
		ISimpleJpaRepository<?, ?> repository = getTargetRepository(
				information, iEntityManager);
		// repository.setRepositoryMethodMetadata(lockModePostProcessor.getLockMetadataProvider());
		return repository;
	}

	@Override
	protected <T, ID extends Serializable> ISimpleJpaRepository<?, ?> getTargetRepository(
			RepositoryInformation information, EntityManager entityManager) {
		JpaEntityInformation<?, Serializable> entityInformation = getEntityInformation(information
				.getDomainType());
		return getTargetRepositoryViaReflection(information, entityInformation,
				entityManager);
	}

	@Override
	protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {

		if (isQueryDslExecutor(metadata.getRepositoryInterface())) {
			return QueryDslJpaRepository.class;
		} else {
			return ISimpleJpaRepository.class;
		}
	}

	private boolean isQueryDslExecutor(Class<?> repositoryInterface) {
		return QUERY_DSL_PRESENT
				&& QueryDslPredicateExecutor.class
						.isAssignableFrom(repositoryInterface);
	}

}
